package util

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"hy_808/global"
	"hy_808/protocol/hygprs"
	"strconv"
	"strings"
)

// 根据端序 字节转有符号整型
func Toint16ByOrder(v []byte, order string) int16 {
	var n int16
	if order == "little" {
		binary.Read(bytes.NewBuffer(v), binary.LittleEndian, &n)
	} else {
		binary.Read(bytes.NewBuffer(v), binary.BigEndian, &n)
	}
	return n
}

func AddrToByte4(addr string) []byte {
	var s []byte
	strs := strings.Split(addr, ":")
	strs1 := strings.Split(strs[0], ".")
	//ip
	for _, s2 := range strs1 {
		n, _ := strconv.Atoi(s2)
		s = append(s, byte(n))
	}
	//端口
	m, _ := strconv.Atoi(strs[1])
	s = append(s, hygprs.FromUint16(uint16(m))...)
	return s
}

// 字符串转字节 指定长度 指定填充位置 指定填充值
func StrToBytesWithFill(s string, n int, fillPos string, fillVal byte) []byte {
	bf := make([]byte, n)
	bf = bytes.ReplaceAll(bf, []byte{0}, []byte{fillVal})
	b := []byte(s)
	l := len(b)
	if l > n {
		copy(bf, b[l-n:l])
	} else {
		if fillPos == "left" { //左侧填充0
			copy(bf[n-l:], b)
		} else { //右侧填充 默认拷贝左边，右侧填0
			copy(bf, b)
		}

	}
	return bf
}

// 解析BCD码为字符串
func Bcd2Number(bcd []byte) string {
	var number string
	for _, i := range bcd {
		number += fmt.Sprintf("%02X", i)
	}
	pos := strings.LastIndex(number, "F")
	if pos == 8 {
		return "0"
	}
	return number[pos+1:]
}

func Number2bcd(number string) []byte {
	var rNumber = number
	for i := 0; i < 8-len(number); i++ {
		rNumber = "f" + rNumber
	}
	bcd := Hex2Byte(rNumber)
	return bcd
}

func Hex2Byte(str string) []byte {
	slen := len(str)
	bHex := make([]byte, len(str)/2)
	ii := 0
	for i := 0; i < len(str); i = i + 2 {
		if slen != 1 {
			ss := string(str[i]) + string(str[i+1])
			bt, _ := strconv.ParseInt(ss, 16, 32)
			bHex[ii] = byte(bt)
			ii = ii + 1
			slen = slen - 2
		}
	}
	return bHex
}

/*
*
字符串补全
*/
func FillStr(s, f, pos string, l int) string {
	if len(s) >= l {
		return s
	}
	//长度相差数
	c := l - len(s)
	if pos == "left" {
		return strings.Repeat(f, c) + s
	} else {
		return s + strings.Repeat(f, c)
	}

}

func GetDeviceDBData(deviceNo int) (global.DeviceDBData, error) {
	if v, ok := global.DeviceDBDataMap.Load(deviceNo); ok {
		d, _ := v.(global.DeviceDBData)
		return d, nil
	} else {
		return global.DeviceDBData{}, errors.New("未找到DeviceDBData")
	}
}
